﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using LERP.Domain;
using LERP.Domain.Enums;
using LERP.Web.Controllers.ViewModels.OrderViewModels;
using Newtonsoft.Json;
using Sharp.Framework;
using Sharp.Framework.Extensions;
using Sharp.Framework.Queries;
using SharpArch.NHibernate.Web.Mvc;

namespace LERP.Web.Controllers
{
    public class OrderController : BaseController
    {
        private readonly IQuery _query;

        public OrderController(IQuery query)
        {
            _query = query;
        }
        /// <summary>
        /// 订单统计
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="customer"></param>
        /// <param name="month"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public ActionResult Count(int? userId, int? customer, string month, int[] status, int customerType = 0, int page = 1, int size = 12)
        {
           
                ViewBag.Users = _query.FindAll<User>().Where(m => m.Stauts == DataStatus.Normal && m.Role == UserRole.User).Select(
                    x => new SelectListItem { Text = x.Name, Value = x.Id.ToString(CultureInfo.InvariantCulture) }).ToList
                    ();
          

            DateTime currentMonth;
            if (!DateTime.TryParseExact(month, "yyyyMM", CultureInfo.CurrentCulture, DateTimeStyles.None, out currentMonth))
            {
                currentMonth = DateTime.Now;
            }

           

            if (null == status)
            {
                status = new int[0];
            }

            var query = _query.FindAll<Order>().Where(m => m.OrderDate.Year == currentMonth.Year && m.OrderDate.Month == currentMonth.Month && status.Contains((int)m.Status));
            if (userId.HasValue)
            {
                query = query.Where(m => m.Creater.Id == userId.Value);
            }
            if (customer.HasValue)
            {
                switch (customerType)
                {
                    case 0:
                        query = query.Where(m => m.Customer.Parent.Parent.Id == customer.Value);
                        break;
                    case 1:
                        query = query.Where(m => m.Customer.Parent.Id == customer.Value);
                        break;
                    case 2:
                        query = query.Where(m => m.Customer.Id == customer.Value);
                        break;
                }
            }
            if (query.Any())
            {
                ViewBag.Total = new ReturnOrderTotal
                {
                    AmountSum = query.Sum(x => x.Amount),
                    Count = query.Count(),
                    WarehouseAmountSum = query.Sum(x => x.WarehouseAmount)
                };

            }
            var model = query.OrderByDescending(m => m.Modified).Select(m => new OrderListViewModel()
            {
                Id = m.Id,
                Customer = m.Customer.Name,
                Amount = m.Amount,
                Created = m.Created,
                CustomerOrderNo = m.CustomerOrderNo,
                ExpectDelivery = m.ExpectDelivery,
                LogisticsProvider =
                    (m.LogisticsProvider == null)
                        ? ""
                        : m.LogisticsProvider.Name,
                Status = m.Status,
                Confirmation = m.Confirmation

            }).ToPagedList(page, size);


            return View(model);
        }

        /// <summary>
        /// 订单查询
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="status"></param>
        /// <param name="keyword"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns> 
        public ActionResult Index(int? userId, int? status, string keyword, int page = 1, int size = 12)
        {
            ViewBag.UserRole = Current.Role;
            if (Current.Role == UserRole.User)
            {
                userId = Current.Id;
            }
            else
            {
                ViewBag.Users =
                    _query.FindAll<User>().Where(m => m.Stauts == DataStatus.Normal && m.Role == UserRole.User).Select(
                        x => new SelectListItem {Text = x.Name, Value = x.Id.ToString(CultureInfo.InvariantCulture)}).
                        ToList
                        ();
                ;

            }

            var query = _query.FindAll<Order>();
            if (userId.HasValue)
            {
                query = query.Where(m => m.Creater.Id == userId.Value);
            }
            if (status.HasValue)
            {
                query = query.Where(m => m.Status == (OrderStatus) status.Value);
            }
            if (!string.IsNullOrEmpty(keyword))
            {
                query = query.Where(m => m.Customer.Name.Contains(keyword));
            }
            var model = query.OrderByDescending(m => m.Modified).Select(m => new OrderListViewModel()
                                                                                 {
                                                                                     Id = m.Id,
                                                                                     Customer = m.Customer.Name,
                                                                                     Amount = m.Amount,
                                                                                     Created = m.Created,
                                                                                     CustomerOrderNo = m.CustomerOrderNo,
                                                                                     ExpectDelivery = m.ExpectDelivery,
                                                                                     LogisticsProvider =
                                                                                         (m.LogisticsProvider == null)
                                                                                             ? ""
                                                                                             : m.LogisticsProvider.Name,
                                                                                     Status = m.Status,
                                                                                     Confirmation = m.Confirmation

                                                                                 }).ToPagedList(page, size);
            return View(model);
        }

        /// <summary>
        /// 查看订单详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ActionResult Details(int id, string returnUrl)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            var goods =
                _query.FindAll<OrderItem>().Where(m => m.Order == model).Select(m => new GoodsSelectItemViewModel
                                                                                         {
                                                                                             Id = m.Goods.Id,
                                                                                             Name = m.Goods.Name,
                                                                                             Number = m.OrderNum,
                                                                                             Price = m.Price,
                                                                                             ShortName =
                                                                                                 m.Goods.Name.CutString(
                                                                                                     64),
                                                                                             CarrierNum =
                                                                                                 m.CarrierNum.HasValue
                                                                                                     ? m.CarrierNum.
                                                                                                           Value
                                                                                                     : m.OrderNum,
                                                                                             ReceivedNum =
                                                                                                 m.ReceivedNum.HasValue
                                                                                                     ? m.ReceivedNum.
                                                                                                           Value
                                                                                                     : m.OrderNum,
                                                                                             SellUnit = m.Goods.SellUnit,
                                                                                             Gencod = string.IsNullOrEmpty(m.Goods.Gencod) ? string.Empty : m.Goods.Gencod
                                                                                         }).ToList();
            ViewBag.OrderItems = model.IsGoods ? JsonConvert.SerializeObject(goods) : "";

            var remarks = new List<OrderRemarkViewModel>();
            if (!string.IsNullOrEmpty(model.Remark))
            {
                remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(model.Remark);
            }

            ViewBag.Remarks = remarks;
            return View(model);
        }

        /// <summary>
        /// 订单打印
        /// </summary>
        /// <param name="id"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public ActionResult Print(int id, int page = 1, int size = 20)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            ViewBag.Current = Current;

            ViewBag.Page = page;
            ViewBag.Size = size;


            return View(model);
        }

        /// <summary>
        /// 新建订单
        /// </summary>
        /// <returns></returns>
        public ActionResult Create()
        { 
            ViewBag.Contracts = GetContracts();
            return View(new CreateOrderViveModel
                            {
                                ExpectDelivery = DateTime.Now.AddDays(3).ToString("yyyy-MM-dd"),
                                IsGoods = true,
                                OrderDate = DateTime.Now.ToString("yyyy-MM-dd"),
                                Status = (int)OrderStatus.Draft
                            });
        }
        /// <summary>
        /// 获取物流列表
        /// </summary>
        /// <returns></returns>
        private List<SelectListItem> GetLogisticsProviders()
        {
            return _query.FindAll<LogisticsProvider>().Where(m => m.Stauts == DataStatus.Normal).Select(
                x => new SelectListItem {Text = x.Name, Value = x.Id.ToString(CultureInfo.InvariantCulture)}).ToList
                ();
        }

        /// <summary>
        /// 获取合同列表
        /// </summary>
        /// <returns></returns>
        private List<SelectListItem> GetContracts()
        {
            return
                _query.FindAll<Contract>()
                      .Where(
                          x => x.Stauts == DataStatus.Normal && x.BeginTime <= DateTime.Now && x.EndTime >= DateTime.Now)
                      .Select(m => new SelectListItem {Text = string.Format("[{0}]{1}({2}~{3})", m.Code, m.Subsidiary.Name, m.BeginTime.ToString("yyyy-MM-dd"), m.EndTime.ToString("yyyy-MM-dd")), Value = m.Id.ToString(CultureInfo.InvariantCulture)})
                      .ToList();
        }

        /// <summary>
        /// 新建订单提交
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public ActionResult Create(CreateOrderViveModel model)
        {

            try
            {
                if (ModelState.IsValid)
                {

                    var entity = new Order();
                    var customer = _query.Get<Customer>(model.CustomerId);
                    if (null == customer)
                    {
                        ModelState.AddModelError("Customer", "客户不存在,请重新选择"); 
                        ViewBag.Contracts = GetContracts();
                        return View(model);
                    }
                    var contract = _query.Get<Contract>(model.Contract);
                    if (null == contract)
                    {
                        ModelState.AddModelError("Contract", "合同不存在,请重新选择"); 
                        ViewBag.Contracts = GetContracts();
                        return View(model);
                    }
                    GoodsSelectItemViewModel[] goodsList = null;
                    if (model.IsGoods)
                    {
                        goodsList =
                            JsonConvert.DeserializeObject<GoodsSelectItemViewModel[]>(model.OrderItems);
                        if (null == goodsList || goodsList.Length == 0)
                        {
                            ModelState.AddModelError("", "发货货品不能为空"); 
                            ViewBag.Contracts = GetContracts();
                            return View();
                        }
                        entity.Amount = goodsList.Sum(m => m.Price*m.Number);
                    }
                    else
                    {
                        entity.Amount = model.Amount;
                    }


                    LogisticsProvider logisticsProvider = null;
                    if (model.LogisticsProvider.HasValue)
                    {
                        logisticsProvider = _query.Get<LogisticsProvider>(model.LogisticsProvider.Value);
                    }
                    entity.CarrierCode = model.CarrierCode;
                    entity.Confirmation = false;
                    entity.Created = DateTime.Now;
                    entity.Modified = DateTime.Now;
                    entity.Creater = Current;
                    entity.Customer = customer;
                    entity.Contract = contract;
                    entity.CustomerOrderNo = model.CustomerOrderNo;
                    entity.DeliveryNo = model.DeliveryNo;
                    entity.ExpectDelivery =DateTime.Parse( model.ExpectDelivery);
                    entity.WarehouseAmount = 0;
                    entity.PaymentAmount = entity.Amount;
                    entity.WarehouseCode = model.WarehouseCode;
                    entity.TangibleDelivery = null;
                    entity.IsGoods = model.IsGoods;
                    entity.LogisticsProvider = logisticsProvider;
                    entity.SafeNo = model.SafeNo;
                    entity.Status = (OrderStatus) model.Status;
                    entity.OrderDate =DateTime.Parse( model.OrderDate);

                    entity.Remark = JsonConvert.SerializeObject(new List<OrderRemarkViewModel>
                                                                                    {
                                                                                        new OrderRemarkViewModel
                                                                                            {
                                                                                                Action =
                                                                                                    string.IsNullOrEmpty
                                                                                                        (model.Remark)
                                                                                                        ? "创建订单"
                                                                                                        : string.Format(
                                                                                                            "创建订单:{0}",
                                                                                                            model.Remark),
                                                                                                UserName =
                                                                                                    Current.Name,
                                                                                                UserId = Current.Id,
                                                                                                Created =
                                                                                                    DateTime.Now
                                                                                            }
                                                                                    });
                  

                    _query.Save(entity);
                    if (goodsList != null)
                    {
                        foreach (var item in goodsList)
                        {
                            var goods = _query.Get<Goods>(item.Id);
                            var orderItem = new OrderItem
                                                {
                                                    Order = entity,
                                                    Goods = goods,
                                                    CarrierNum = item.CarrierNum,
                                                    OrderNum = item.Number,
                                                    Price = item.Price,
                                                    ReceivedNum = item.ReceivedNum
                                                };
                            _query.Save(orderItem);
                        }
                    }
                    return RedirectToAction("Index", "Order");
                }
            }
            catch
            {
                ModelState.AddModelError("", "系统繁忙,请稍后再试");
            }
             
            ViewBag.Contracts = GetContracts();
            return View(model);
        }

        /// <summary>
        /// 添加备注
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ActionResult Remark(int id, string returnUrl)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            var remarks = new List<OrderRemarkViewModel>();
            if (!string.IsNullOrEmpty(model.Remark))
            {
                remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(model.Remark);
            }

            ViewBag.Remarks = remarks;
            return View(model);
        }


        /// <summary>
        /// 添加备注提交
        /// </summary>
        /// <param name="id"></param>
        /// <param name="newremark"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public ActionResult Remark(int id, string newremark, string returnUrl)
        {
            try
            {

                if (ModelState.IsValid)
                {

                    var entity = _query.Get<Order>(id);
                    if (null == entity)
                    {
                        return View("NoFound");
                    }
                    if (!string.IsNullOrEmpty(newremark))
                    {
                        var remarks = new List<OrderRemarkViewModel>();
                        if (!string.IsNullOrEmpty(entity.Remark))
                        {
                            remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
                        }
                        remarks.Add(new OrderRemarkViewModel
                                        {
                                            Action = string.Format("{0}", newremark),
                                            UserName = Current.Name,
                                            UserId = Current.Id,
                                            Created = DateTime.Now
                                        });
                        entity.Remark = JsonConvert.SerializeObject(remarks);
                    }
                    _query.Save(entity);

                    if (string.IsNullOrEmpty(returnUrl))
                    {
                        return RedirectToAction("Index");
                    }
                    return Redirect(returnUrl);

                }
            }
            catch
            {
                ModelState.AddModelError("", "系统繁忙,请稍后再试");
            }


            return View();
        }


        /// <summary>
        /// 修改订单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ActionResult Edit(int id, string returnUrl)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            var goods =
                _query.FindAll<OrderItem>().Where(m => m.Order == model).Select(m => new GoodsSelectItemViewModel
                                                                                         {
                                                                                             Id = m.Goods.Id,
                                                                                             Name = m.Goods.Name,
                                                                                             Number = m.OrderNum,
                                                                                             Price = m.Price,
                                                                                             ShortName =
                                                                                                 m.Goods.Name.CutString(
                                                                                                     64),
                                                                                             CarrierNum =
                                                                                                 m.CarrierNum.HasValue
                                                                                                     ? m.CarrierNum.
                                                                                                           Value
                                                                                                     : m.OrderNum,
                                                                                             ReceivedNum =
                                                                                                 m.ReceivedNum.HasValue
                                                                                                     ? m.ReceivedNum.
                                                                                                           Value
                                                                                                     : m.OrderNum,
                                                                                             SellUnit = m.Goods.SellUnit,
                                                                                             Gencod = string.IsNullOrEmpty(m.Goods.Gencod) ? string.Empty : m.Goods.Gencod
                                                                                         }).ToList();
            decimal amount = model.IsGoods ? goods.Sum(m => m.Price*m.Number) : model.Amount;
            ;
            var entity = new ModifyOrderViveModel
                             {
                                 CarrierCode = model.CarrierCode,
                                 Customer = model.Customer.Parent.Parent.Name + model.Customer.Parent.Name + model.Customer.Name,
                                 CustomerId = model.Customer.Id,
                                 CustomerOrderNo = model.CustomerOrderNo,
                                 DeliveryNo = model.DeliveryNo,
                                 ExpectDelivery = model.ExpectDelivery.ToString("yyyy-MM-dd"),
                                 TangibleDelivery =model.TangibleDelivery.HasValue? model.TangibleDelivery.Value.ToString("yyyy-MM-dd"):null,
                                 IsGoods = model.IsGoods,
                                 SafeNo = model.SafeNo,
                                 Status = (int) model.Status,
                                 Amount = amount,
                                 OrderItems =
                                     model.IsGoods ? JsonConvert.SerializeObject(goods) : string.Empty,
                                 WarehouseCode = model.WarehouseCode,
                                 Confirmation = model.Confirmation,
                                 OrderDate = model.OrderDate.ToString("yyyy-MM-dd"),
                                 Contract = model.Contract.Id,
                                 ContractName = string.Format("[{0}]{1}({2}~{3})", model.Contract.Code, model.Contract.Subsidiary.Name, model.Contract.BeginTime.ToString("yyyy-MM-dd"), model.Contract.EndTime.ToString("yyyy-MM-dd"))


                             };
            if (null != model.LogisticsProvider)
            {
                entity.LogisticsProvider = model.LogisticsProvider.Id;
            }


            ViewBag.OrderStatus = GetOrderStatus();
            ViewBag.LogisticsProviders = GetLogisticsProviders();
            ViewBag.Contracts = GetContracts();
            return View(entity);
        }


        /// <summary>
        /// 修改订单提交
        /// </summary>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public ActionResult Edit(int id, ModifyOrderViveModel model, string returnUrl)
        {
            try
            {

                if (ModelState.IsValid)
                {

                    var entity = _query.Get<Order>(id);
                    if (null == entity)
                    {
                        return View("NoFound");
                    }
                    var customer = _query.Get<Customer>(model.CustomerId);
                    if (null == customer)
                    {
                        ModelState.AddModelError("Customer", "客户不存在,请重新选择"); 
                        ViewBag.OrderStatus = GetOrderStatus();
                        ViewBag.LogisticsProviders = GetLogisticsProviders();
                        ViewBag.Contracts = GetContracts();
                        return View(model);
                    }
                    var contract = _query.Get<Contract>(model.Contract);
                    if (null == contract)
                    {
                        ModelState.AddModelError("Contract", "合同不存在,请重新选择");
                        ViewBag.OrderStatus = GetOrderStatus();
                        ViewBag.LogisticsProviders = GetLogisticsProviders();
                        ViewBag.Contracts = GetContracts();
                        return View();
                    }
                    GoodsSelectItemViewModel[] goodsList = null;
                    if (model.IsGoods)
                    { 
                        goodsList =
                            JsonConvert.DeserializeObject<GoodsSelectItemViewModel[]>(model.OrderItems);
                        if (null == goodsList || goodsList.Length == 0)
                        {
                            ModelState.AddModelError("", "发货货品不能为空"); 
                            ViewBag.OrderStatus = GetOrderStatus();
                            ViewBag.LogisticsProviders = GetLogisticsProviders();
                            ViewBag.Contracts = GetContracts();
                            return View(model);
                        }
                        entity.Amount = goodsList.Sum(m => m.Price*m.CarrierNum);
                        entity.PaymentAmount = goodsList.Sum(m => m.Price*m.ReceivedNum);
                        entity.WarehouseAmount = entity.Amount - entity.PaymentAmount.Value;
                    }
                    else
                    {
                        entity.Amount = model.Amount;
                        entity.PaymentAmount = model.Amount;
                        entity.WarehouseAmount = entity.Amount - entity.PaymentAmount.Value;
                    }


                    LogisticsProvider logisticsProvider = null;
                    if (model.LogisticsProvider.HasValue)
                    {
                        logisticsProvider = _query.Get<LogisticsProvider>(model.LogisticsProvider.Value);
                    }
                    entity.CarrierCode = model.CarrierCode;
                    entity.Confirmation = model.Confirmation; 
                    entity.Modified = DateTime.Now;
                    entity.Creater = Current;
                    entity.Customer = customer;
                    entity.Contract = contract;
                    entity.CustomerOrderNo = model.CustomerOrderNo;
                    entity.DeliveryNo = model.DeliveryNo;
                    entity.ExpectDelivery = DateTime.Parse(model.ExpectDelivery);
                    entity.WarehouseCode = model.WarehouseCode;
                     
                    entity.IsGoods = model.IsGoods;
                    entity.LogisticsProvider = logisticsProvider;
                    entity.SafeNo = model.SafeNo; 
                    entity.OrderDate = DateTime.Parse(model.OrderDate);

                    var remarks = new List<OrderRemarkViewModel>();
                    if (!string.IsNullOrEmpty(entity.Remark))
                    {
                        remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
                    }
                    remarks.Add(new OrderRemarkViewModel
                                    {
                                        Action =
                                            string.IsNullOrEmpty(model.Remark)
                                                ? "修改订单信息"
                                                : string.Format("修改订单:{0}", model.Remark),
                                        UserName = Current.Name,
                                        UserId = Current.Id,
                                        Created = DateTime.Now
                                    });
                    entity.Remark = JsonConvert.SerializeObject(remarks);
                    if (!string.IsNullOrEmpty(model.TangibleDelivery))
                    {
                        entity.TangibleDelivery = DateTime.Parse(model.TangibleDelivery);
                    }
                    if(model.Confirmation&&entity.Status==OrderStatus.WaitForReceipt)
                    {
                        entity.Status = OrderStatus.Receipted;
                    }
                    _query.Save(entity);
                    if (goodsList != null&&goodsList.Any())
                    {
                        var goodIds = goodsList.Select(x => x.Id).ToArray();
                        var items = _query.FindAll<OrderItem>().Where(x=>x.Order == entity).ToList();
                        //删除移除的订单商品
                        foreach (var item in items.Where(x => !goodIds.Contains(x.Goods.Id)))
                        {
                            _query.Delete(item);
                        }
                        foreach (var item in goodsList)
                        {
                            var orderItem = items.FirstOrDefault(
                                    m => m.Order == entity && m.Goods.Id == item.Id);
                            if (null == orderItem)
                            {
                                var goods = _query.Get<Goods>(item.Id); 
                                orderItem = new OrderItem
                                                {
                                                    Goods = goods,
                                                    Order = entity
                                                };
                            }
                            if (entity.Status == OrderStatus.Draft)
                            {
                                orderItem.OrderNum = item.Number;
                            }
                            orderItem.Price = entity.Status == OrderStatus.Draft ? item.Price : orderItem.Price;
                            orderItem.CarrierNum = entity.Status == OrderStatus.ToBeShipped ? item.CarrierNum : orderItem.CarrierNum;
                            orderItem.ReceivedNum = entity.Status == OrderStatus.ToBeReceived ? item.ReceivedNum : orderItem.ReceivedNum;
                            _query.Save(orderItem);
                        }
                    }else
                    { 
                        //删除移除的订单商品
                        foreach (var item in _query.FindAll<OrderItem>().Where(x => x.Order == entity).ToList())
                        {
                            _query.Delete(item);
                        }
                    }
                    if (string.IsNullOrEmpty(returnUrl))
                    {
                        return RedirectToAction("Index");
                    }
                    return Redirect(returnUrl);

                }
            }
            catch
            {
                ModelState.AddModelError("", "系统繁忙,请稍后再试");
            }

            ViewBag.OrderStatus = GetOrderStatus();
            ViewBag.LogisticsProviders = GetLogisticsProviders();
            ViewBag.Contracts = GetContracts();
            return View(model);
        }



        /// <summary>
        /// 订单发货
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ActionResult Shipped(int id, string returnUrl)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            var goods =
                _query.FindAll<OrderItem>().Where(m => m.Order == model).Select(m => new GoodsSelectItemViewModel
                {
                    Id = m.Goods.Id,
                    Name = m.Goods.Name,
                    Number = m.OrderNum,
                    Price = m.Price,
                    ShortName =
                        m.Goods.Name.CutString(
                            64),
                    CarrierNum =
                        m.CarrierNum.HasValue
                            ? m.CarrierNum.
                                  Value
                            : m.OrderNum,
                    ReceivedNum =
                        m.ReceivedNum.HasValue
                            ? m.ReceivedNum.
                                  Value
                            : m.OrderNum,
                    SellUnit = m.Goods.SellUnit,
                    Gencod = string.IsNullOrEmpty(m.Goods.Gencod) ? string.Empty : m.Goods.Gencod
                }).ToList();
            decimal amount = model.IsGoods ? goods.Sum(m => m.Price * m.Number) : model.Amount;
            ;
            var entity = new ShippedOrderViveModel
            {
                CarrierCode = model.CarrierCode,
                Customer = model.Customer.Parent.Parent.Name + model.Customer.Parent.Name + model.Customer.Name,
                CustomerOrderNo = model.CustomerOrderNo,
                DeliveryNo = model.DeliveryNo,
                ExpectDelivery = model.ExpectDelivery.ToString("yyyy-MM-dd"),
                IsGoods = model.IsGoods,
                SafeNo = model.SafeNo,
                Status = (int)model.Status,
                Amount = amount,
                OrderItems =
                    model.IsGoods ? JsonConvert.SerializeObject(goods) : string.Empty,
                OrderDate = model.OrderDate.ToString("yyyy-MM-dd"),
                ContractName = string.Format("[{0}]{1}({2}~{3})", model.Contract.Code, model.Contract.Subsidiary.Name, model.Contract.BeginTime.ToString("yyyy-MM-dd"), model.Contract.EndTime.ToString("yyyy-MM-dd"))


            };
            if (null != model.LogisticsProvider)
            {
                entity.LogisticsProvider = model.LogisticsProvider.Id;
            }



            ViewBag.OrderStatus = GetOrderStatus();
            ViewBag.LogisticsProviders = GetLogisticsProviders();
            return View(entity);
        }


        /// <summary>
        /// 订单发货提交
        /// </summary>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public ActionResult Shipped(int id, ShippedOrderViveModel model, string returnUrl)
        {
            try
            {

                if (ModelState.IsValid)
                {

                    var entity = _query.Get<Order>(id);
                    if (null == entity)
                    {
                        return View("NoFound");
                    } 
                    GoodsSelectItemViewModel[] goodsList = null;
                    if (model.IsGoods)
                    {
                        goodsList =
                            JsonConvert.DeserializeObject<GoodsSelectItemViewModel[]>(model.OrderItems);
                        if (null == goodsList || goodsList.Length == 0)
                        {
                            ModelState.AddModelError("", "发货货品不能为空");
                            ViewBag.OrderStatus = GetOrderStatus();
                            ViewBag.LogisticsProviders = GetLogisticsProviders();
                            return View(model);
                        }
                        entity.Amount = goodsList.Sum(m => m.Price * m.CarrierNum);
                        entity.PaymentAmount = entity.Amount;
                    }
                    else
                    {
                        entity.Amount = model.Amount;
                        entity.PaymentAmount = model.Amount; 
                    }


                    LogisticsProvider logisticsProvider = null;
                    if (model.LogisticsProvider.HasValue)
                    {
                        logisticsProvider = _query.Get<LogisticsProvider>(model.LogisticsProvider.Value);
                    }

                    entity.Modified = DateTime.Now; 
                    entity.CarrierCode = model.CarrierCode;   
                    entity.DeliveryNo = model.DeliveryNo;
                    entity.ExpectDelivery =DateTime.Parse( model.ExpectDelivery);  
                    entity.LogisticsProvider = logisticsProvider;
                    entity.SafeNo = model.SafeNo; 
                    entity.Status = OrderStatus.ToBeReceived;
                    var remarks = new List<OrderRemarkViewModel>();
                    if (!string.IsNullOrEmpty(entity.Remark))
                    {
                        remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
                    }
                    remarks.Add(new OrderRemarkViewModel
                    {
                        Action =
                            string.IsNullOrEmpty(model.Remark)
                                ? "订单发货"
                                : string.Format("订单发货:{0}", model.Remark),
                        UserName = Current.Name,
                        UserId = Current.Id,
                        Created = DateTime.Now
                    });
                    entity.Remark = JsonConvert.SerializeObject(remarks);
                     

                    _query.Save(entity);
                    if (goodsList != null && goodsList.Any())
                    {
                        var items = _query.FindAll<OrderItem>().Where(x => x.Order == entity).ToList();
                        foreach (var item in items)
                        {
                            var orderItem = goodsList.FirstOrDefault(
                                    m => item.Goods.Id == m.Id);
                            if (null != orderItem)
                            {
                                item.CarrierNum = orderItem.CarrierNum;
                                item.ReceivedNum = orderItem.CarrierNum;
                                _query.Save(item);
                            } 
                        }
                    }
                    if (string.IsNullOrEmpty(returnUrl))
                    {
                        return RedirectToAction("Index");
                    }
                    return Redirect(returnUrl);

                }
            }
            catch
            {
                ModelState.AddModelError("", "系统繁忙,请稍后再试");
            }

            ViewBag.OrderStatus = GetOrderStatus();
            ViewBag.LogisticsProviders = GetLogisticsProviders();
            return View(model);
        }

        /// <summary>
        /// 订单收货
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ActionResult Received(int id, string returnUrl)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            var goods =
                _query.FindAll<OrderItem>().Where(m => m.Order == model).Select(m => new GoodsSelectItemViewModel
                {
                    Id = m.Goods.Id,
                    Name = m.Goods.Name,
                    Number = m.OrderNum,
                    Price = m.Price,
                    ShortName =
                        m.Goods.Name.CutString(
                            64),
                    CarrierNum =
                        m.CarrierNum.HasValue
                            ? m.CarrierNum.
                                  Value
                            : m.OrderNum,
                    ReceivedNum =
                        m.ReceivedNum.HasValue
                            ? m.ReceivedNum.
                                  Value
                            : m.OrderNum,
                    SellUnit = m.Goods.SellUnit,
                    Gencod = string.IsNullOrEmpty(m.Goods.Gencod) ? string.Empty : m.Goods.Gencod
                }).ToList();
            decimal amount = model.IsGoods ? goods.Sum(m => m.Price * m.Number) : model.Amount;
            ;
            var entity = new ReceivedOrderViveModel
            {
                CarrierCode = model.CarrierCode,
                Customer = model.Customer.Parent.Parent.Name + model.Customer.Parent.Name + model.Customer.Name,
                CustomerOrderNo = model.CustomerOrderNo,
                DeliveryNo = model.DeliveryNo,
                ExpectDelivery = model.ExpectDelivery.ToString("yyyy-MM-dd"),
                IsGoods = model.IsGoods,
                SafeNo = model.SafeNo,
                Status = (int)model.Status,
                Amount = amount,
                OrderItems =
                    model.IsGoods ? JsonConvert.SerializeObject(goods) : string.Empty,
                OrderDate = model.OrderDate.ToString("yyyy-MM-dd"),
                LogisticsProvider = model.LogisticsProvider!=null?model.LogisticsProvider.Name:"",
                Remark = "",
                TangibleDelivery = (model.TangibleDelivery.HasValue ? model.TangibleDelivery.Value : DateTime.Now).ToString("yyyy-MM-dd"),
                ContractName = string.Format("[{0}]{1}({2}~{3})", model.Contract.Code, model.Contract.Subsidiary.Name, model.Contract.BeginTime.ToString("yyyy-MM-dd"), model.Contract.EndTime.ToString("yyyy-MM-dd")) 
            }; 
            return View(entity);
        }


        /// <summary>
        /// 订单收货提交
        /// </summary>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public ActionResult Received(int id, ReceivedOrderViveModel model, string returnUrl)
        {
            try
            { 
                if (ModelState.IsValid)
                { 
                    var entity = _query.Get<Order>(id);
                    if (null == entity)
                    {
                        return View("NoFound");
                    } 
                    GoodsSelectItemViewModel[] goodsList = null;
                    if (model.IsGoods)
                    {
                        goodsList =
                            JsonConvert.DeserializeObject<GoodsSelectItemViewModel[]>(model.OrderItems);
                         
                        entity.PaymentAmount = goodsList.Sum(m => m.Price * m.ReceivedNum);
                        entity.WarehouseAmount = entity.Amount - entity.PaymentAmount.Value;
                    }
                    else
                    {
                        entity.Amount = model.Amount;
                        entity.PaymentAmount = model.Amount; 
                    } 

                    entity.Modified = DateTime.Now;
                    entity.ExpectDelivery = DateTime.Parse(model.ExpectDelivery); 
                    if (!string.IsNullOrEmpty(model.TangibleDelivery))
                    {
                        entity.TangibleDelivery = DateTime.Parse(model.TangibleDelivery);
                    }
                    entity.Status =entity.WarehouseAmount==0? OrderStatus.WaitForReceipt:OrderStatus.Recount;
                    var remarks = new List<OrderRemarkViewModel>();
                    if (!string.IsNullOrEmpty(entity.Remark))
                    {
                        remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
                    }
                    remarks.Add(new OrderRemarkViewModel
                    {
                        Action =
                            string.IsNullOrEmpty(model.Remark)
                                ? "订单收货"
                                : string.Format("订单收货:{0}", model.Remark),
                        UserName = Current.Name,
                        UserId = Current.Id,
                        Created = DateTime.Now
                    });
                    entity.Remark = JsonConvert.SerializeObject(remarks);
                     

                    _query.Save(entity);
                    if (goodsList != null && goodsList.Any())
                    {
                        var items = _query.FindAll<OrderItem>().Where(m => m.Order == entity).ToList();
                        foreach (var item in items)
                        {
                            var orderItem = goodsList.FirstOrDefault(
                                    m => item.Goods.Id == m.Id);
                            if (null != orderItem)
                            { 
                                item.ReceivedNum = orderItem.ReceivedNum;
                                _query.Save(item);
                            } 
                        }
                    }
                    if (string.IsNullOrEmpty(returnUrl))
                    {
                        return RedirectToAction("Index");
                    }
                    return Redirect(returnUrl);

                }
            }
            catch
            {
                ModelState.AddModelError("", "系统繁忙,请稍后再试");
            } 
            return View(model);
        }
   
        /// <summary>
        /// 提交订单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ActionResult Apply(int id, string returnUrl)
        {
            var model = _query.Get<Order>(id);
            if (null == model)
            {
                return View("NoFound");
            }
            var goods =
                _query.FindAll<OrderItem>().Where(m => m.Order == model).Select(m => new GoodsSelectItemViewModel
                {
                    Id = m.Goods.Id,
                    Name = m.Goods.Name,
                    Number = m.OrderNum,
                    Price = m.Price,
                    ShortName =
                        m.Goods.Name.CutString(
                            64),
                    CarrierNum =
                        m.CarrierNum.HasValue
                            ? m.CarrierNum.
                                  Value
                            : m.OrderNum,
                    ReceivedNum =
                        m.ReceivedNum.HasValue
                            ? m.ReceivedNum.
                                  Value
                            : m.OrderNum,
                    SellUnit = m.Goods.SellUnit,
                    Gencod = string.IsNullOrEmpty(m.Goods.Gencod) ? string.Empty : m.Goods.Gencod
                }).ToList();
            decimal amount = model.IsGoods ? goods.Sum(m => m.Price * m.Number) : model.Amount;
            ;
            var entity = new ApplyOrderViveModel
            {
                Customer = model.Customer.Parent.Parent.Name + model.Customer.Parent.Name + model.Customer.Name,
                CustomerId = model.Customer.Id,
                CustomerOrderNo = model.CustomerOrderNo,
                ExpectDelivery = model.ExpectDelivery.ToString("yyyy-MM-dd"), 
                IsGoods = model.IsGoods, 
                Status = (int)model.Status,
                Amount = amount,
                OrderItems =
                    model.IsGoods ? JsonConvert.SerializeObject(goods) : string.Empty,
                OrderDate = model.OrderDate.ToString("yyyy-MM-dd"),
                Contract = model.Contract.Id

            };
            ViewBag.Contracts = GetContracts(); 
            return View(entity);
        }

        /// <summary>
        /// 提交订单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [HttpPost]
        [Transaction]
        public ActionResult Apply(int id, ApplyOrderViveModel model, string returnUrl)
        {
            try
            {

                if (ModelState.IsValid)
                {

                    var entity = _query.Get<Order>(id);
                    if (null == entity)
                    {
                        return View("NoFound");
                    }
                    var customer = _query.Get<Customer>(model.CustomerId);
                    if (null == customer)
                    {
                        ModelState.AddModelError("Customer", "客户不存在,请重新选择");
                        ViewBag.Contracts = GetContracts();
                        return View(model);
                    }
                    var contract = _query.Get<Contract>(model.Contract);
                    if (null == contract)
                    {
                        ModelState.AddModelError("Contract", "合同不存在,请重新选择");
                        ViewBag.Contracts = GetContracts();
                        return View();
                    }
                    GoodsSelectItemViewModel[] goodsList = null;
                    if (model.IsGoods)
                    {
                        goodsList = JsonConvert.DeserializeObject<GoodsSelectItemViewModel[]>(model.OrderItems);
                        if (null == goodsList || goodsList.Length == 0)
                        {
                            ModelState.AddModelError("", "发货货品不能为空");
                            ViewBag.Contracts = GetContracts();
                            return View(model);
                        }
                        entity.Amount = goodsList.Sum(m => m.Price*m.CarrierNum);
                        entity.PaymentAmount = entity.Amount; 
                    }
                    else
                    {
                        entity.Amount = model.Amount;
                        entity.PaymentAmount = model.Amount; 
                    }
                    entity.Modified = DateTime.Now;
                    entity.Creater = Current;
                    entity.Customer = customer;
                    entity.CustomerOrderNo = model.CustomerOrderNo;
                    entity.ExpectDelivery =DateTime.Parse( model.ExpectDelivery);
                     
                    entity.IsGoods = model.IsGoods;
                    entity.Status = OrderStatus.ToBeShipped;
                    entity.OrderDate = DateTime.Parse(model.OrderDate);
                    entity.Contract = contract;

                    var remarks = new List<OrderRemarkViewModel>();
                    if (!string.IsNullOrEmpty(entity.Remark))
                    {
                        remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
                    }
                    remarks.Add(new OrderRemarkViewModel
                                    {
                                        Action =
                                            string.IsNullOrEmpty(model.Remark)
                                                ? "提交订单"
                                                : string.Format("提交订单:{0}", model.Remark),
                                        UserName = Current.Name,
                                        UserId = Current.Id,
                                        Created = DateTime.Now
                                    });
                    entity.Remark = JsonConvert.SerializeObject(remarks);

                    _query.Save(entity);
                    if (goodsList != null && goodsList.Any())
                    {
                        var goodIds = goodsList.Select(x => x.Id).ToArray();
                        var items = _query.FindAll<OrderItem>().Where(x=>x.Order == entity).ToList();
                        //删除移除的订单商品
                        foreach (var item in items.Where(x => !goodIds.Contains(x.Goods.Id)))
                        {
                            _query.Delete(item);
                        }
                        foreach (var item in goodsList)
                        {
                            var orderItem = items.FirstOrDefault(
                                m => m.Order == entity && m.Goods.Id == item.Id);
                            if (null == orderItem)
                            {
                                orderItem = new OrderItem
                                                {
                                                    Goods = _query.Get<Goods>(item.Id),
                                                    Order = entity
                                                };
                            }
                            orderItem.OrderNum = item.Number;
                            orderItem.Price = item.Price; 
                            orderItem.CarrierNum = item.Number;
                            orderItem.ReceivedNum = item.Number;
                            _query.Save(orderItem);
                        }
                    }
                    else
                    {
                        //删除移除的订单商品
                        foreach (var item in _query.FindAll<OrderItem>().Where(m => m.Order == entity).ToList())
                        {
                            _query.Delete(item);
                        }
                    }
                    if (string.IsNullOrEmpty(returnUrl))
                    {
                        return RedirectToAction("Index");
                    }
                    return Redirect(returnUrl);

                }
            }
            catch
            {
                ModelState.AddModelError("", "系统繁忙,请稍后再试");
            }
            ViewBag.Contracts = GetContracts();
            return View(model);
        }



        private static List<SelectListItem> GetOrderStatus()
        {
            return
                OrderStatus.Close.ToDictionary().Where(
                    m => m.Value != (int) OrderStatus.Close && m.Value != (int) OrderStatus.Cancel).Select(
                        m => new SelectListItem {Text = m.Key, Value = m.Value.ToString(CultureInfo.InvariantCulture)}).
                    ToList();
        }


 

         
        /// <summary>
        /// 删除订单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"> </param>
        /// <returns></returns>
        [Transaction]
        [HttpGet]
        public ActionResult Delete(int id, string returnUrl)
        {
            var entity = _query.Get<Order>(id);

            if (null == entity)
            {
                return View("NoFound");
            }
            foreach (var item in _query.FindAll<OrderItem>().Where(m => m.Order == entity))
            {
                _query.Delete(item);

            }
            _query.Delete(entity);
            if (string.IsNullOrEmpty(returnUrl))
            {
                return RedirectToAction("Index");
            }
            return Redirect(returnUrl);
        }

        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [Transaction]
        [HttpGet]
        public ActionResult Cancel(int id, string returnUrl)
        {
            var entity = _query.Get<Order>(id);
            if (null == entity)
            {
                return View("NoFound");
            }
            entity.Status = OrderStatus.Cancel;
            var remarks = new List<OrderRemarkViewModel>();
            if (!string.IsNullOrEmpty(entity.Remark))
            {
                remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
            }
            remarks.Add(new OrderRemarkViewModel
            {
                Action =   "取消订单",
                UserName = Current.Name,
                UserId = Current.Id,
                Created = DateTime.Now
            });
            entity.Remark = JsonConvert.SerializeObject(remarks);
            _query.Save(entity);
            if (string.IsNullOrEmpty(returnUrl))
            {
                return RedirectToAction("Index");
            }
            return Redirect(returnUrl);
        }

        /// <summary>
        /// 关闭订单
        /// </summary>
        /// <param name="id"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        [Transaction]
        [HttpGet]
        public ActionResult Close(int id, string returnUrl)
        {
            var entity = _query.Get<Order>(id);
            if (null == entity)
            {
                return View("NoFound");
            }
            entity.Status = OrderStatus.Close;
            var remarks = new List<OrderRemarkViewModel>();
            if (!string.IsNullOrEmpty(entity.Remark))
            {
                remarks = JsonConvert.DeserializeObject<List<OrderRemarkViewModel>>(entity.Remark);
            }
            remarks.Add(new OrderRemarkViewModel
            {
                Action = "关闭订单",
                UserName = Current.Name,
                UserId = Current.Id,
                Created = DateTime.Now
            });
            _query.Save(entity);
            if (string.IsNullOrEmpty(returnUrl))
            {
                return RedirectToAction("Index");
            }
            return Redirect(returnUrl);
        }
         
    }
}
